#include<iostream> #include<cstdio> #include<cstring> #define x first #define y second using namespace std; const int MOD = 1e9 + 7; typedef long long ll;
pair<int, int> edge[2505]; int head[21], net[2505], ver[2505], idx; int n, a[21][21], tot; bool is[21];
void add(int a, int b) { net[++idx] = head[a], ver[idx] = b, head[a] = idx; }
int qmi(int a, int b) { int res = 1; while (b) { if (b & 1) res = (ll)res * a % MOD; a = (ll)a * a % MOD; b >>= 1; } return res; }
int work() { int res = 1, w = 1; for (int i = 1; i < n; i++) { for (int j = i + 1; j < n; j++) { if (a[j][i] && !a[i][i]) { swap(a[j], a[i]), w = -w; break; } } int inv = qmi(a[i][i], MOD - 2); for (int j = i + 1; j < n; j++) { int temp = (ll)a[j][i] * inv % MOD; for (int k = i; k < n; k++) a[j][k] = (a[j][k] - (ll)a[i][k] * temp % MOD) % MOD; } } for (int i = 1; i < n; i++) res = (ll)res * a[i][i] % MOD; res *= w; return (res % MOD + MOD) % MOD; }
int dfs(int ned, int last) { if (ned == 0) { memset(a, 0, sizeof(a)); int t = 0; for (int i = 1; i < n; i++) { if (is[i]) continue; t++; for (int j = head[i]; j; j = net[j]) { int v = ver[j]; int xx = edge[v].x, yy = edge[v].y; a[xx][xx]++, a[yy][yy]++; a[xx][yy]--, a[yy][xx]--; } } return work(); } int res = 0; for (int i = last; i < n; i++) { if (is[i]) continue; is[i] = true; res = ((ll)res + dfs(ned - 1, i)) % MOD; is[i] = false; } return res; }
int main() { scanf("%d", &n); for (int i = 1; i < n; i++) { int m; scanf("%d", &m); for (int j = 1; j <= m; j++) { int u, v; scanf("%d%d", &u, &v); edge[++tot] = make_pair(u, v); add(i, tot); } } int ans = 0, w = 1; for (int i = 0; i < n; i++) ans = (ans + dfs(i, 1) * w) % MOD, w = -w; printf("%d", (ans % MOD + MOD) % MOD); return 0; }